﻿using System;
using System.IO;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

namespace OpenXmlEasy.Word
{
    public partial class WordEasy : IDisposable
    {
        private readonly WordprocessingDocument _doc;
        private Body _body;

        private UInt32Value _elementId = 1U;
        private int _tableCount;
        private int _imageCount;

        public static int CommonId = 1;

        #region constructors

        public WordEasy(string fileFullName)
        {
            _doc = WordprocessingDocument.Create(fileFullName, WordprocessingDocumentType.Document);
            InitDocument();
        }

        public WordEasy(Stream stream)
        {
            _doc = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document);
            InitDocument();
        }

        #endregion

        private void InitDocument()
        {
            var mainDocumentPart = _doc.AddMainDocumentPart();
            var document = new Document { MCAttributes = new MarkupCompatibilityAttributes { Ignorable = "w14 wp14" } };
            {
                document.AddNamespaceDeclaration("wpc", "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas");
                document.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
                document.AddNamespaceDeclaration("o", "urn:schemas-microsoft-com:office:office");
                document.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
                document.AddNamespaceDeclaration("m", "http://schemas.openxmlformats.org/officeDocument/2006/math");
                document.AddNamespaceDeclaration("v", "urn:schemas-microsoft-com:vml");
                document.AddNamespaceDeclaration("wp14", "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing");
                document.AddNamespaceDeclaration("wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing");
                document.AddNamespaceDeclaration("w10", "urn:schemas-microsoft-com:office:word");
                document.AddNamespaceDeclaration("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
                document.AddNamespaceDeclaration("w14", "http://schemas.microsoft.com/office/word/2010/wordml");
                document.AddNamespaceDeclaration("wpg", "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup");
                document.AddNamespaceDeclaration("wpi", "http://schemas.microsoft.com/office/word/2010/wordprocessingInk");
                document.AddNamespaceDeclaration("wne", "http://schemas.microsoft.com/office/word/2006/wordml");
                document.AddNamespaceDeclaration("wps", "http://schemas.microsoft.com/office/word/2010/wordprocessingShape");
            }
            mainDocumentPart.Document = document;
            _body = document.AppendChild(new Body());

            StyleSetter.CreateParagraphStyle(_doc);
        }

        public void InsertBreak(int tableCoumnCount)
        {
            //10  纵 //10-20 横  //20-30 拆纵  //30+ 拆横
            if ((tableCoumnCount > 10 && tableCoumnCount <= 20)
                || (tableCoumnCount > 30))
            {
                SetPageLandscape();
            }
            else
            {
                SetPagePortrait();
            }
        }

        public void Save()
        {
            var sectionProperties = new SectionProperties();
            var pageSize = new PageSize { Height = 16838U, Width = 11906U };
            var pageMargin = new PageMargin { Top = 1440, Right = 1080U, Bottom = 1440, Left = 1080U, Header = 851U, Footer = 992U, Gutter = 0U };
            var docGrid = new DocGrid { Type = DocGridValues.Lines, LinePitch = 312 };
            sectionProperties.AppendChild(pageSize);
            sectionProperties.AppendChild(pageMargin);
            sectionProperties.AppendChild(docGrid);
            _body.AppendChild(sectionProperties);
        }

        #region Dispose

        private bool _disposed = false;

        /// <summary>
        /// 实现IDisposable中的Dispose方法
        /// </summary>
        public void Dispose()
        {
            //必须为true
            Dispose(true);
            //通知垃圾回收机制不再调用终结器（析构器）
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 不是必要的，提供一个Close方法仅仅是为了更符合其他语言（如C++）的规范
        /// </summary>
        public void Close()
        {
            Dispose();
        }

        /// <summary>
        /// 必须，以备程序员忘记了显式调用Dispose方法
        /// </summary>
        ~WordEasy()
        {
            //必须为false
            Dispose(false);
        }

        /// <summary>
        /// 非密封类修饰用protected virtual
        /// 密封类修饰用private
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }
            if (disposing)
            {
                // 清理托管资源
                if (_doc != null)
                {
                    _doc.Dispose();
                }
            }
            // 清理非托管资源
            //if (nativeResource != IntPtr.Zero)
            //{
            //    Marshal.FreeHGlobal(nativeResource);
            //    nativeResource = IntPtr.Zero;
            //}
            //让类型知道自己已经被释放
            _disposed = true;
        }

        #endregion
    }
}
